﻿using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.FileProviders.Physical;
using Microsoft.Extensions.Primitives;
using System;
using System.IO;
using System.Linq;

namespace Batman.Cms.Core.Razor
{
    public class DeveloperViewFileProvider : IFileProvider
    {
        public DeveloperViewFileProvider(IHostingEnvironment hostingEnvironment)
        {
            HostingEnvironment = hostingEnvironment;
        }
        public IDirectoryContents GetDirectoryContents(string subpath)
        {
            return null;
        }

        public IHostingEnvironment HostingEnvironment { get; }

        public IFileInfo GetFileInfo(string subpath)
        {
            if (subpath.StartsWith("/Porject.RootPath/", StringComparison.Ordinal))
            {
                var parent = new DirectoryInfo(HostingEnvironment.ContentRootPath).Parent;

                var file = Path.Combine(parent.FullName, subpath.Replace("/Porject.RootPath/", "Batman.Cms.Core/").ToFilePath());
                if (File.Exists(file)) return new PhysicalFileInfo(new FileInfo(file));
            }
            else if (subpath.Contains("EditorTemplates"))
            {
                var parent = new DirectoryInfo(HostingEnvironment.ContentRootPath).Parent;

                var file = Path.Combine(parent.FullName, "Batman.Cms.Core/" + subpath);
                if (File.Exists(file)) return new PhysicalFileInfo(new FileInfo(file));

                file = Path.Combine(HostingEnvironment.ContentRootPath, subpath.TrimStart('/'));
                if (File.Exists(file)) return new PhysicalFileInfo(new FileInfo(file));
            }
            else
            {
                // 适应于微服务，分割斜杠组成数组，如果数组的第二个是css js dist images中的一个，
                // 则可以认为是微服务下加了前缀，在这里进行数据分割
                // 也因此需要在开发过程中进行文件夹有所规范

                var splits = subpath.Trim('/').Split('/');
                var folders = new string[] { "css", "js", "dist", "images" };
                if (splits.Length >= 2 && folders.Contains(splits[1]))
                {
                    splits.ToList().RemoveAt(0);
                    var file = Path.Combine(HostingEnvironment.WebRootPath, string.Join("/", splits));
                    if (File.Exists(file)) return new PhysicalFileInfo(new FileInfo(file));
                }
            }

            return null;
        }

        public IChangeToken Watch(string filter)
        {
            if (filter.StartsWith("/Porject.RootPath/", StringComparison.Ordinal))
            {
                var parent = new DirectoryInfo(HostingEnvironment.ContentRootPath).Parent;

                var file = Path.Combine(parent.FullName, filter.Replace("/Porject.RootPath/", "").ToFilePath());
                if (File.Exists(file)) return new PollingFileChangeToken(new FileInfo(file));
            }
            return null;
        }
    }

    public static class ExtString
    {
        public static string ToFilePath(this string path)
        {
            return string.Join(Path.DirectorySeparatorChar.ToString(), path.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));
        }
    }
}
